package cn.yunsenlin.formula.cloud.template;

import cn.yunsenlin.formula.cloud.bean.auth.Template;
import cn.yunsenlin.formula.cloud.bean.template.TemplateShareParams;
import cn.yunsenlin.formula.cloud.interfaces.TemplateService;
import cn.yunsenlin.formula.cloud.mysql.bean.generator.*;
import cn.yunsenlin.formula.cloud.mysql.mapper.custom.TemplateMapper;
import cn.yunsenlin.formula.cloud.mysql.mapper.generator.TbColumnMapper;
import cn.yunsenlin.formula.cloud.mysql.mapper.generator.TbResultMapper;
import cn.yunsenlin.formula.cloud.mysql.mapper.generator.TbTemplateMapper;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class TemplateServiceImpl implements TemplateService {
    private final TbColumnMapper tbColumnMapper;
    private final TbTemplateMapper tbTemplateMapper;
    private final TbResultMapper tbResultMapper;
    private final TemplateMapper templateMapper;

    @SuppressWarnings("all")
    public TemplateServiceImpl(TbColumnMapper tbColumnMapper, TbTemplateMapper tbTemplateMapper, TbResultMapper tbResultMapper, TemplateMapper templateMapper) {
        this.tbColumnMapper = tbColumnMapper;
        this.tbTemplateMapper = tbTemplateMapper;
        this.tbResultMapper = tbResultMapper;
        this.templateMapper = templateMapper;
    }

    @Override
    public Template createTemplate(Template template,int userId) {
        template.getBaseInfo().setUserId(userId);
        template.getBaseInfo().setShareEncryption(false);
        template.getBaseInfo().setShareStorage(false);
        template.getBaseInfo().setShare(false);
        tbTemplateMapper.insert(template.getBaseInfo());
        template.getInput().forEach(tbColumn -> {
            tbColumn.setType("input");
            tbColumn.setTemplateId(template.getBaseInfo().getId());
            tbColumnMapper.insert(tbColumn);
        });
        template.getOutput().forEach(tbColumn -> {
            tbColumn.setType("output");
            tbColumn.setTemplateId(template.getBaseInfo().getId());
            tbColumnMapper.insert(tbColumn);
        });
        return template;
    }

    @Override
    public Template createTempTemplate(Template template) {
        return createTemplate(template,0);
    }

    @Override
    public Template updateTemplateBaseInfo(TbTemplate tbTemplate) {
        tbTemplateMapper.updateByPrimaryKey(tbTemplate);
        return selectById(tbTemplate.getId());
    }

    @Override
    public Template shareTemplate(int templateId, TemplateShareParams params) {
        Template template = selectById(templateId);
        template.getBaseInfo().setShareEncryption(params.isEncryption());
        template.getBaseInfo().setShareStorage(params.isStorage());
        template.getBaseInfo().setShare(params.isShare());
        template.getBaseInfo().setShareEncryptionPassword(params.getEncryptionPassword());
        template.getBaseInfo().setShareUuid(UUID.randomUUID().toString().replace("-",""));
        return updateTemplateBaseInfo(template.getBaseInfo());
    }

    @Override
    public void removeTemplate(int id) {
        if(!templateIsUsing(id)){
            TbColumnCriteria columnCriteria =new TbColumnCriteria();
            columnCriteria.or().andTemplateIdEqualTo(id);
            tbColumnMapper.deleteByExample(columnCriteria);
            tbTemplateMapper.deleteByPrimaryKey(id);
        }
    }

    @Override
    public boolean templateIsUsing(int id) {
        TbResultCriteria criteria = new TbResultCriteria();
        criteria.or().andTemplateIdEqualTo(id);
        return tbResultMapper.selectByExample(criteria).size()>0;
    }

    @Override
    public boolean templateNameIsRepeat(String name,int userId) {
        TbTemplateCriteria criteria = new TbTemplateCriteria();
        criteria.or().andUserIdEqualTo(userId).andNameEqualTo(name);
        return tbTemplateMapper.selectByExample(criteria).size()>0;
    }

    @Override
    public List<TbTemplate> selectByUserId(int userId) {
        TbTemplateCriteria criteria = new TbTemplateCriteria();
        criteria.or().andUserIdEqualTo(userId);
        return tbTemplateMapper.selectByExample(criteria);
    }

    @Override
    public Template selectById(int id) {
        Template template = new Template();
        template.setBaseInfo(tbTemplateMapper.selectByPrimaryKey(id));
        TbColumnCriteria inputCriteria = new TbColumnCriteria();
        TbColumnCriteria outputCriteria = new TbColumnCriteria();
        inputCriteria.or().andTemplateIdEqualTo(id).andTypeEqualTo("input");
        outputCriteria.or().andTemplateIdEqualTo(id).andTypeEqualTo("output");
        template.setInput(tbColumnMapper.selectByExample(inputCriteria));
        template.setOutput(tbColumnMapper.selectByExample(outputCriteria));
        template.setAmount(getAmount(id));
        return template;
    }

    @Override
    public List<Template> selectTemplateByGroupId(Integer groupId) {
        List<Template> templates = new ArrayList<>();
        templateMapper.selectByGroupId(groupId).forEach(tbTemplate -> templates.add(selectById(tbTemplate.getId())));
        return templates;
    }

    @Override
    public Integer getAmount(int templateId){
        TbResultCriteria resultCriteria = new TbResultCriteria();
        resultCriteria.or().andTemplateIdEqualTo(templateId);
        return tbResultMapper.countByExample(resultCriteria);
    }
}
